package com.olympus.hermes.common.constants;

import javax.persistence.AttributeConverter;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

/**
 * @author Mickey
 * @since 2021/2/5
 */
public class EnumConverter<E extends Enum<E> & BaseEnum<E>> implements AttributeConverter<BaseEnum<E>, Integer> {


    private final Method valuesMethod;

    @SuppressWarnings("unchecked")
    public EnumConverter() {
        Class<E> xclazz = (Class<E>) (((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments())[0];
        try {
            valuesMethod = xclazz.getMethod("values");
        } catch (Exception e) {
            throw new RuntimeException("can't get values method from " + xclazz);
        }
    }

    @Override
    public Integer convertToDatabaseColumn(BaseEnum<E> attribute) {
        return attribute == null ? null : attribute.getCode();
    }

    @Override
    public E convertToEntityAttribute(Integer code) {
        try {
            E[] values = (E[]) valuesMethod.invoke(null);
            for (E x : values) {
                if (x.getCode().equals(code)) {
                    return x;
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("can't convertToEntityAttribute" + e.getMessage());
        }
        throw new RuntimeException("unknown dbData " + code);
    }
}
